/*
 *  This file is part of WWWPal.
 *
 *  Copyright (C) 2003  Dr. John Punin, Department of Computer Science
 *  Rensselaer Polytechnic Institute
 *
 *  WWWPal is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  WWWPal is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "client.h"
#include "partition.h"
#include "second_part.h"
#include "report_map.h"

static int min_nodes;
static int max_tree; 
static char report;
static int first_time =0;

int
second_partition_algorithm(mainFrame *mf, int mn, int mt,char rep)
{
  int count = count_llist(mf->ltgr_frame);
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  tgrFrame *maptgf;

  report = rep;

  first_time =0;
  if(mn != 0)
    min_nodes = mn;
  else
    min_nodes = MIN_NODES;
  if(mt != 0)
    max_tree = mt;
  else
    max_tree = MAX_TREE;

  if(count > 1)
    {
    fprintf(stderr,"Sorry, there are more than one graph to be partitioned\n");
      return 0;
    }

  /* We trust that the graph is connected and 
     the root of the tree is node 1 */
  maptgf = create_directed_graph(mf);

  second_select_and_group(mf,tgf,maptgf);

  if(maptgf->root)
    {
      set_vertex_position(maptgf->root, GR_MWIDTH/2, 20);
      compute_tree_positions(maptgf->gf,maptgf->root,NORTH);
    }
  if(!maptgf->filename)
    {
      maptgf->filename = malloc(strlen(mf->basename)+10);
      if(!maptgf->filename) {
	  fprintf(stderr,"Out of Memory second_partition_algorithm\n");
	  abort();
      }
      sprintf(maptgf->filename, "%smap.gr", mf->basename);
    }
  save_current_graph(maptgf);

  if(rep == 'y')
    {
      char *nf= malloc(strlen(mf->basename)+15);
      if(!nf) {
	  fprintf(stderr,"Out of Memory second_partition_algorithm\n");
	  abort();
      }
      sprintf(nf, "%smap.html", mf->basename);
      report_map_site(mf, maptgf, nf, maptgf->root, 0,0,0);
      free(nf); nf = NULL;
    }
  return 1;
}

char *
second_select_and_group(mainFrame *mf,tgrFrame *tgf,tgrFrame *maptgf)
{
  move_cur_to_tgf(mf,tgf);
 
  if(second_select_best_nodes(mf, tgf))
    {
      char *result;
      struct pt *cgv = NULL;
      tgrFrame *btgr=NULL, *gtgr=NULL;
      
      btgr = execute_browsing(mf);
      btgr->root = find_vertex_by_name(btgr->gf,get_label_vertex(tgf->broot));
      set_root_vertex(btgr->gf,btgr->root);

      result = second_select_and_group(mf, btgr,maptgf);

      move_cur_to_tgf(mf,tgf);
      gtgr = execute_grouping(mf);

      cgv = gtgr->gf->cgv;
      gtgr->gf->cgv = NULL;
      gtgr->root = find_vertex_by_name(gtgr->gf,get_label_vertex(tgf->root));
      set_root_vertex(gtgr->gf,gtgr->root);

      if(result)
	{
	  printf("Result  %s \n", result);
	  if(cgv)
	    {
	      struct pt *mv = find_vertex_by_name(maptgf->gf,result);
	      printf("Changing label to %s - %s\n", cgv->label, result);
	      change_label_vertex(gtgr->gf, cgv, result);

	      if(mv)
		change_weight_vertex(gtgr->gf, cgv, get_weight_vertex(mv));

	      copy_attributes(cgv,tgf->broot);
	      add_attribute(cgv,"ROOT_URL",get_label_vertex(tgf->broot)); 
	      free(result); result = NULL;
	    }
	  else
	    printf("No current group vertex \n");
	}
      else
	printf("NO Result \n");

      erase_frame(mf,tgf);

      return(second_select_and_group(mf, gtgr,maptgf));

    }
  else
    {
      char *location = NULL;

      if(!tgf->filename)
	tgf->filename = create_new_name(mf);

      add_node_to_map(mf, tgf, maptgf);

      if(tgf->root)
	{
	  int mes;
	  tgf->root->loc.x = 500;
	  tgf->root->loc.y = 500;
	  set_no_class_edge(tgf->gf,True);
	  mes = compute_radial_tree_positions(tgf->gf,tgf->root);
	  set_no_class_edge(tgf->gf,False);
	  move_graph_to_given_position(tgf->gf,50, 50);
	}
      save_current_graph(tgf);

      if(report == 'y')
	{
	  char *nf= change_end_name(tgf->filename,"gr", "html");
	  report_map_site(mf, tgf, nf, tgf->root, 0,0,1);
	  free(nf); nf = NULL;
	}

      GRStrAllocCopy(location,tgf->filename);

      erase_frame(mf,tgf);
      
      return location;
    }
}

int
second_select_best_nodes(mainFrame *mf, tgrFrame *tgf)
{
  GraphFrame *gf = tgf->gf;
  int numobj = count_llist(get_list_objects(gf));
  struct pt *v = tgf->root;
  struct pt *nv;

  if(v)
    {
	/*set_method_tree(gf, BFS_FV_TREE);*/
      set_cost_function(gf, get_weight_out_degree_node_to);
      set_method_tree(gf,SHORTEST_PATH_FV_TREE);
      compute_tree_graph(gf,v);
      set_method_tree(gf, BFS_TREE);
      if(there_are_no_pick_nodes(gf))
	{
	  printf("\tCOMPLETING BFS\n");
	  complete_bfs_directed(gf,v);
	}
    }
  else
    {
      printf("NO ROOT TREE\n");
      return 0;
    }
  /*  printf("RADIAL TREE DRAWING FINISHED\n");*/
  if((get_count_vertex(gf)-numobj) < min_nodes)
    {
      /*printf("THIS TREE HAS LESS THAN %d NODES\n", min_nodes);*/
      return 0;
    }
  printf("CHOOSING FIRST TREE\n");
  nv = choose_first_tree_by_template(gf,v, max_tree);

  if(nv && nv!=v)
    {
      printf("CHOOSING FIRST TREE BY TEMPLATE WAS MADE\n");
      printf("New vertex : %d, %s \n", nv->num, nv->label);
      mf->nroot = nv;
      tgf->broot = nv;
      return select_tree_by_template(gf, nv);
    }
  printf("CHOOSING BEST TREE\n");
  nv = choose_best_tree(gf,v, max_tree);
  if(nv && nv !=v)
    {
      printf("New vertex : %d, %s \n", nv->num, nv->label);
      mf->nroot = nv;
      tgf->broot = nv;
      return select_tree(gf, nv);
    }

  printf("NO SELECTION WAS MADE for tree %s\n", v->label);
  return 0;
}












